package com.zjut.an.util.tools;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;

import javax.crypto.Cipher;
import javax.crypto.CipherInputStream;
import javax.crypto.CipherOutputStream;
import javax.crypto.KeyGenerator;
import javax.crypto.NoSuchPaddingException;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;

/**
 * 对文件压缩加密/解密解压缩 对象类
 * 
 */
public class ZipEncrypt {
	 
	 /**
	  * 初始化 AES Cipher
	  * @param sKey
	  * @param cipherMode
	  * @return
	  */
	 public static Cipher initAESCipher(String sKey, int cipherMode) {
	     //创建Key gen
	     KeyGenerator keyGenerator = null;
	     Cipher cipher = null;
	     try {
	    	 keyGenerator = KeyGenerator.getInstance("AES");
	         SecureRandom secureRandom = SecureRandom.getInstance("SHA1PRNG");
	         secureRandom.setSeed(sKey.getBytes()); 
	         keyGenerator.init(128, secureRandom);;
	         SecretKey secretKey = keyGenerator.generateKey();
	         byte[] codeFormat = secretKey.getEncoded();
	         SecretKeySpec key = new SecretKeySpec(codeFormat, "AES");
	         cipher = Cipher.getInstance("AES");
	         //初始化
	         cipher.init(cipherMode, key);
	     } catch (NoSuchAlgorithmException e) {
	         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
	     } catch (NoSuchPaddingException e) {
	         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
	     } catch (InvalidKeyException e) {
	         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
	     }
	     return cipher;
	 }
	 
	 /**
	  * 对文件进行AES加密
	  * @param sourceFile
	  * @param fileType
	  * @param sKey
	  * @return
	  */
	 public static File encryptFile(File sourceFile, String encrypt, String sKey){
	     //新建临时加密文件
	     File encrypfile = null;
	     InputStream inputStream = null;
	     OutputStream outputStream = null;
	     try {
	         inputStream = new FileInputStream(sourceFile);
	         //encrypfile = File.createTempFile(sourceFile.getName(), fileType);
	         encrypfile = new File(encrypt);
	         ////System.out.println(encrypfile.getAbsolutePath());
	         //encrypfile = new File(encrypfile);
	         outputStream = new FileOutputStream(encrypfile);
	         Cipher cipher = initAESCipher(sKey,Cipher.ENCRYPT_MODE);
	         //以加密流写入文件
	         CipherInputStream cipherInputStream = new CipherInputStream(inputStream, cipher);
	         byte[] cache = new byte[1024];
	         int nRead = 0;
	         while ((nRead = cipherInputStream.read(cache)) != -1) {
	             outputStream.write(cache, 0, nRead);
	             outputStream.flush();
	         }
	         cipherInputStream.close();
	     }  catch (FileNotFoundException e) {
	         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
	     }  catch (IOException e) {
	         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
	     } finally {
	         try {
	             inputStream.close();
	         } catch (IOException e) {
	             e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
	         }
	         try {
	             outputStream.close();
	         } catch (IOException e) {
	             e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
	         }
	     }
	     return encrypfile;
	 }
	 
	 /**
	  * AES方式解密文件
	  * @param sourceFile
	  * @return
	  */
	 public static File decryptFile(File sourceFile, String zipPath, String sKey){
	     File decryptFile = null;
	     InputStream inputStream = null;
	     OutputStream outputStream = null;
	     try {
	         //decryptFile = File.createTempFile(sourceFile.getName(),fileType);
	         decryptFile = new File(zipPath);
	         Cipher cipher = initAESCipher(sKey,Cipher.DECRYPT_MODE);
	         inputStream = new FileInputStream(sourceFile);
	         outputStream = new FileOutputStream(decryptFile);
	         CipherOutputStream cipherOutputStream = new CipherOutputStream(outputStream, cipher);
	         byte [] buffer = new byte [1024];
	         int r;
	         while ((r = inputStream.read(buffer)) >= 0) {
	             cipherOutputStream.write(buffer, 0, r);
	         }
	         cipherOutputStream.close();
	     } catch (IOException e) {
	         e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
	     }finally {
	         try {
	             inputStream.close();
	         } catch (IOException e) {
	             e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
	         }
	         try {
	             outputStream.close();
	         } catch (IOException e) {
	             e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
	         }
	     }
	     return decryptFile;
	 }
	 
	 
	 

	 /*public static void main(String args[]) throws Exception {
		 
		 //File f = new File("D:/谭陈.zip");
		 //File f = new File("D:/zip.cmp");
		 //encryptFile(f, "zip", "sgj");
		 //decryptFile(f, "zip", "sgj");
	 }*/
	}